package com.info.zhiduoduo.admin.service;

import com.alibaba.fastjson.JSON;
import com.alipay.api.AlipayApiException;
import com.alipay.api.domain.ExtCardInfo;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.response.AlipayDataBillAccountbookereceiptQueryResponse;
import com.alipay.api.response.AlipayDataBillEreceiptagentApplyResponse;
import com.alipay.api.response.AlipayFundAccountbookCreateResponse;
import com.alipay.api.response.AlipayFundAccountbookQueryResponse;
import com.alipay.api.response.AlipayFundTransCommonQueryResponse;
import com.alipay.api.response.AlipayFundTransUniTransferResponse;
import com.alipay.api.response.AlipayUserAgreementQueryResponse;
import com.baomidou.mybatisplus.mapper.Condition;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.info.zhiduoduo.admin.model.dto.alipay.AlipayUserAgreementPageSingNotifyModel;
import com.info.zhiduoduo.admin.model.formbean.account.MakerLabelFormBean;
import com.info.zhiduoduo.admin.model.formbean.alipay.AlipayAccountFormBean;
import com.info.zhiduoduo.admin.model.formbean.alipay.AlipayPrincipalAccountRechargeFormBean;
import com.info.zhiduoduo.admin.model.formbean.alipay.MakerIsvIdFormBean;
import com.info.zhiduoduo.admin.model.formbean.alipay.MakerPrincipalIdFormBean;
import com.info.zhiduoduo.admin.model.formbean.alipay.PrincipalPayPublicAccountFormBean;
import com.info.zhiduoduo.admin.model.formbean.alipay.PrincipalTransferPrincipalPublicAccountFormBean;
import com.info.zhiduoduo.admin.model.formbean.entrust.ListMakerAlipayFormBean;
import com.info.zhiduoduo.admin.model.formbean.entrust.ListPrincipalFlowFormBean;
import com.info.zhiduoduo.alipay.config.base.BaseAlipayConfig;
import com.info.zhiduoduo.alipay.constant.AlipayAgreementStatusEnum;
import com.info.zhiduoduo.alipay.constant.AlipayIdentityEnum;
import com.info.zhiduoduo.alipay.constant.AlipayOrderEnum;
import com.info.zhiduoduo.alipay.constant.AlipayOrderStatusEnum;
import com.info.zhiduoduo.alipay.constant.AlipayPrincipalEnum;
import com.info.zhiduoduo.alipay.model.request.RechargeModel;
import com.info.zhiduoduo.alipay.model.request.TransferModel;
import com.info.zhiduoduo.alipay.service.AliPayApiService;
import com.info.zhiduoduo.common.configs.DocConfig;
import com.info.zhiduoduo.common.configs.NotificationConfig;
import com.info.zhiduoduo.common.constants.Constants;
import com.info.zhiduoduo.common.constants.SmartResult;
import com.info.zhiduoduo.common.constants.StatusMsg;
import com.info.zhiduoduo.common.constants.entrustmentproject.AlipayMakerAccountFlowType;
import com.info.zhiduoduo.common.constants.entrustmentproject.AlipayPrincipalAccountFlowType;
import com.info.zhiduoduo.common.constants.entrustmentproject.EntrustProjectState;
import com.info.zhiduoduo.common.constants.entrustmentproject.EntrustState;
import com.info.zhiduoduo.common.constants.project.CalcAmountType;
import com.info.zhiduoduo.common.constants.project.ProjectType;
import com.info.zhiduoduo.common.exception.Asserts;
import com.info.zhiduoduo.common.exception.SmartException;
import com.info.zhiduoduo.common.formbean.BaseSimpleFormBean;
import com.info.zhiduoduo.common.utils.ContextUtil;
import com.info.zhiduoduo.common.utils.DateUtil;
import com.info.zhiduoduo.common.utils.NumberUtil;
import com.info.zhiduoduo.common.utils.RandomUtil;
import com.info.zhiduoduo.common.utils.StringUtil;
import com.info.zhiduoduo.core.service.*;
import com.info.zhiduoduo.core.service.common.BaseService;
import com.info.zhiduoduo.repository.dto.maker.MakerAlipayAvailableDto;
import com.info.zhiduoduo.repository.dto.maker.MakerAlipayDto;
import com.info.zhiduoduo.repository.dto.maker.MakerAlipayPrincipalDto;
import com.info.zhiduoduo.repository.dto.maker.MakerAlipayPrincipalFlowDto;
import com.info.zhiduoduo.repository.entity.entrustmentproject.EntrustmentProjectItem;
import com.info.zhiduoduo.repository.entity.maker.MakerAlipay;
import com.info.zhiduoduo.repository.entity.maker.MakerAlipayAccountBook;
import com.info.zhiduoduo.repository.entity.maker.MakerAlipayAccountFlow;
import com.info.zhiduoduo.repository.entity.maker.MakerAlipayAccountOrder;
import com.info.zhiduoduo.repository.entity.maker.MakerAlipayAgreement;
import com.info.zhiduoduo.repository.entity.maker.MakerAlipayPrincipal;
import com.info.zhiduoduo.repository.entity.maker.MakerAlipayPrincipalFlow;
import com.info.zhiduoduo.repository.entity.maker.MakerAlipayPrincipalOrder;
import com.info.zhiduoduo.repository.entity.maker.MakerStudio;
import com.info.zhiduoduo.repository.mapper.entrustmentproject.EntrustmentProjectItemMapper;
import com.info.zhiduoduo.repository.mapper.invoice.InvoiceMapper;
import com.info.zhiduoduo.repository.mapper.maker.MakerAlipayAccountBookMapper;
import com.info.zhiduoduo.repository.mapper.maker.MakerAlipayAccountOrderMapper;
import com.info.zhiduoduo.repository.mapper.maker.MakerAlipayAgreementMapper;
import com.info.zhiduoduo.repository.mapper.maker.MakerAlipayMapper;
import com.info.zhiduoduo.repository.mapper.maker.MakerAlipayPrincipalFlowMapper;
import com.info.zhiduoduo.repository.mapper.maker.MakerAlipayPrincipalMapper;
import com.info.zhiduoduo.repository.mapper.maker.MakerAlipayPrincipalOrderMapper;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.util.BiConsumer;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.function.Consumer;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import javax.validation.constraints.Positive;

import lombok.extern.slf4j.Slf4j;

import static com.info.zhiduoduo.common.constants.StatusMsg.StatusMsg_101;
import static com.info.zhiduoduo.common.constants.StatusMsg.StatusMsg_228;
import static com.info.zhiduoduo.common.constants.StatusMsg.StatusMsg_233;
import static com.info.zhiduoduo.common.constants.StatusMsg.StatusMsg_234;
import static com.info.zhiduoduo.common.constants.StatusMsg.StatusMsg_236;
import static com.info.zhiduoduo.common.constants.StatusMsg.StatusMsg_240;
import static com.info.zhiduoduo.common.constants.StatusMsg.StatusMsg_241;
import static com.info.zhiduoduo.common.constants.StatusMsg.StatusMsg_242;
import static com.info.zhiduoduo.common.constants.StatusMsg.StatusMsg_245;
import static com.info.zhiduoduo.common.constants.StatusMsg.StatusMsg_262;
import static com.info.zhiduoduo.common.constants.StatusMsg.StatusMsg_263;

@Service
@Slf4j
public class MakerAliPayService extends BaseService {

	@Autowired
	AliPayApiService aliPayApiService;
	@Autowired
	CoreProjectService coreProjectService;
	@Autowired
	CoreInvoiceService coreInvoiceService;
	@Autowired
	CoreEntrustProjectServcie coreEntrustProjectServcie;
	@Autowired
	CoreMakerAlipayService coreMakerAlipayService;
	@Autowired
	CoreInvoiceAmountService coreInvoiceAmountService;
	@Resource
	InvoiceMapper invoiceMapper;

	@Autowired
	MakerAlipayMapper makerAlipayMapper;
	@Autowired
	MakerAlipayPrincipalMapper makerAlipayPrincipalMapper;
	@Autowired
	MakerAlipayPrincipalFlowMapper makerAlipayPrincipalFlowMapper;
	@Autowired
	MakerAlipayAgreementMapper makerAlipayAgreementMapper;
	@Autowired
	MakerAlipayAccountBookMapper makerAlipayAccountBookMapper;
	@Autowired
	MakerAlipayPrincipalOrderMapper makerAlipayPrincipalOrderMapper;
	@Autowired
	MakerAlipayAccountOrderMapper makerAlipayAccountOrderMapper;
	@Autowired
	EntrustmentProjectItemMapper entrustmentProjectItemMapper;

	@Autowired
	DocConfig docConfig;
	@Autowired
	CommonService commonService;
	@Resource
	WxMessageService wxMessageService;
	@Autowired
	NotificationConfig notificationConfig;

	private static ExecutorService executor = Executors.newSingleThreadExecutor();

	/**
	 * 获取 平台的ISV主体，目前是秀圣企业支付宝账号
	 */
	public AlipayPrincipalEnum getISVPrincipal() {
		return coreMakerAlipayService.getISVPrincipal();
	}

	public String appPayNotify(HttpServletRequest request) {
		return null;
	}

	public SmartResult createZddPrincipalAgreement(BaseSimpleFormBean<Integer> formBean) {
		AlipayPrincipalEnum isvPrincipalEnum = getISVPrincipal();
		@Valid Integer id = formBean.getReqdata();
		AlipayPrincipalEnum entrustPrincipalEnum = AlipayPrincipalEnum.findById(id);
		Asserts.notTrue(entrustPrincipalEnum == isvPrincipalEnum, StatusMsg.StatusMsg_243);
		MakerAlipayPrincipal alipayPrincipal = new MakerAlipayPrincipal().selectById(entrustPrincipalEnum.id);
		Asserts.isTrue(alipayPrincipal == null || StringUtil.isEmpty(alipayPrincipal.getAlipayAgreementNo()), StatusMsg.StatusMsg_244);

		String agreementNo = RandomUtil.createRandomNo("ALI_SIGN_", "");
		if (alipayPrincipal == null) {
			alipayPrincipal = new MakerAlipayPrincipal().setId(entrustPrincipalEnum.id);
		}
		alipayPrincipal.setIsvId(isvPrincipalEnum.id)
				.setIsv(Constants.FALSE)
				.setName(entrustPrincipalEnum.name)
				.setAgreementNo(agreementNo)
				.insertOrUpdate();

		String agreementResult = aliPayApiService.userAgreementPageSign(alipayPrincipal.getAgreementNo(), isvPrincipalEnum);
		HashMap<String, Object> map = Maps.newHashMap();
		map.put("id", alipayPrincipal.getId());
		map.put("url", agreementResult);
		return SmartResult.success(map);
	}

	public SmartResult queryZddPrincipalAgreement(BaseSimpleFormBean<Integer> formBean) {
		@Valid Integer principalId = formBean.getReqdata();
		AlipayPrincipalEnum isvPrincipalEnum = getISVPrincipal();
		MakerAlipayPrincipal alipayPrincipal = new MakerAlipayPrincipal().selectById(principalId);
		Asserts.notNull(alipayPrincipal);

		AlipayUserAgreementQueryResponse response = aliPayApiService.userAgreementQuery(alipayPrincipal.getAgreementNo(),
				isvPrincipalEnum);
		alipayPrincipal.setAlipayAgreementNo(response.getAgreementNo())
				.setPricipalType(response.getPricipalType())
				.setAlipayUserId(response.getPrincipalId())
				.setAlipayLogonId(response.getAlipayLogonId())
				.setSignScene(response.getSignScene())
				.setStatus(response.getStatus())
				.setSignTime(DateUtil.parseDate(response.getSignTime(), DateUtil.FORMAT_STYLE_1))
				.setValidTime(DateUtil.parseDate(response.getValidTime(), DateUtil.FORMAT_STYLE_1))
				.setAlipayLogonId(response.getAlipayLogonId());
		alipayPrincipal.updateById();

		return SmartResult.success(alipayPrincipal);
	}

	public SmartResult createZddPrincipalAccount(BaseSimpleFormBean<Integer> formBean) {
		@Valid Integer principalId = formBean.getReqdata();
		AlipayPrincipalEnum isvPrincipalEnum = getISVPrincipal();
		MakerAlipayPrincipal alipayPrincipal = new MakerAlipayPrincipal().selectById(principalId);
		createZddPrincipalAccount(alipayPrincipal);
		return SmartResult.success();
	}

	private boolean createZddPrincipalAccount(MakerAlipayPrincipal alipayPrincipal) {
		Asserts.notNull(alipayPrincipal);
		Asserts.isEmpty(alipayPrincipal.getAccountBookId(), StatusMsg_245);
		AlipayPrincipalEnum isvEnum = getISVPrincipal();
		AlipayFundAccountbookCreateResponse response = aliPayApiService.fundAccountBookCreate(alipayPrincipal.getAlipayUserId(),
				alipayPrincipal.getAlipayAgreementNo(), isvEnum);
		if (response != null && response.isSuccess()) {
			ExtCardInfo cardInfo = response.getExtCardInfo();
			alipayPrincipal.setAccountBookId(response.getAccountBookId())
					.setBankAccName(cardInfo.getBankAccName())
					.setCardBank(cardInfo.getCardBank())
					.setCardBranch(cardInfo.getCardBranch())
					.setCardDeposit(cardInfo.getCardDeposit())
					.setCardLocation(cardInfo.getCardLocation())
					.setCardNo(cardInfo.getCardNo())
					.setAccountBookStatus(cardInfo.getStatus())
					.updateById();
			return true;
		}
		log.info("创建委托人资金记账本失败");
		return false;
	}

	public SmartResult queryZddPrincipalAccount(BaseSimpleFormBean<Integer> formBean) {
		return SmartResult.success(coreMakerAlipayService.queryZddPrincipalAccount(formBean.getReqdata()));
	}

	public SmartResult<MakerAlipayPrincipalDto> listZddPrincipals(BaseSimpleFormBean formBean) {
		List<MakerAlipayPrincipalDto> list = makerAlipayPrincipalMapper.listValid();
		return SmartResult.success(list);
	}

	/**
	 * 创客绑定企业支付宝账号(或更新),保存支付宝账号信息
	 *
	 * @param formBean
	 * @return
	 */
	public SmartResult bindAlipay(BaseSimpleFormBean<AlipayAccountFormBean> formBean) {
		@Valid AlipayAccountFormBean reqdata = formBean.getReqdata();
		int adminid = formBean.getUserid();
		MakerAlipay makerAlipay = new MakerAlipay();
		BeanUtils.copyProperties(reqdata, makerAlipay);
		makerAlipay.setAdminid(adminid).insertOrUpdate();
		return SmartResult.success();
	}

	/**
	 * 删除企业支付宝账号
	 *
	 * @param formBean
	 * @return
	 */
	public SmartResult deleteBindAlipay(BaseSimpleFormBean<Integer> formBean) {
		MakerAlipay makerAlipay = makerAlipayMapper.selectById(formBean.getReqdata());
		if (makerAlipay == null) {
			return SmartResult.fail(StatusMsg.StatusMsg_201);
		}
		if (makerAlipay.getDeleted() == 0){
			makerAlipay.setDeleted(1).setAdminid(formBean.getUserid()).updateById();
		}else {
			makerAlipay.setDeleted(0).setAdminid(formBean.getUserid()).updateById();
		}
		return SmartResult.success();
	}

	//设置创客标签
	@Transactional
	public SmartResult saveMakerAlipayLabel(BaseSimpleFormBean<MakerLabelFormBean> formBean) {
		MakerLabelFormBean makerAlipayLabel = formBean.getReqdata();

		List<String> labelList = makerAlipayLabel.getMakerLabelList();
		String labels = StringUtils.join(labelList.toArray(), ",");

		String useridStr = makerAlipayLabel.getUserid();
		List<String> userIdlist = new ArrayList(Arrays.asList(useridStr.split(",")));
		for (String userid : userIdlist) {
			//检验数据存在
			MakerAlipay makerAlipay = makerAlipayMapper.selectById(userid);
			if (makerAlipay == null) {
				return SmartResult.fail(StatusMsg.StatusMsg_201);
			}
			//修改标签
			makerAlipay.updateById();
		}
		return SmartResult.success();
	}

	public SmartResult<MakerAlipayDto> listMakerAlipay(BaseSimpleFormBean<ListMakerAlipayFormBean> formBean) {
		@Valid ListMakerAlipayFormBean reqdata = formBean.getReqdata();
		Page<MakerAlipayDto> page = PageHelper.startPage(formBean.getPage(), formBean.getRows());

		reqdata.setMakerLabel(StringUtil.isEmpty(reqdata.getMakerLabel()) ? null : reqdata.getMakerLabel());
		List<MakerAlipayDto> list = makerAlipayMapper.list(reqdata.getCompname(), reqdata.getName(), reqdata.getFrom(), reqdata.getTo(),
				reqdata.getMakerLabel(), reqdata.getFriendlyState(), reqdata.getInvoicescope(),reqdata.getDeleted());
		for (MakerAlipayDto dto : list) {
			dto.setMonthTotalAmount(coreInvoiceAmountService.getUserMonthlyTotalAmount(dto.getUserid()));
			dto.setQuarterTotalAmount(coreInvoiceAmountService.getUserQuarterTotalAmount(dto.getUserid()));
			dto.setYearTotalAmount(coreInvoiceAmountService.getUserYearlyTotalAmount(dto.getUserid()));
			dto.setTwelveMonthAmount(coreInvoiceAmountService.getUserTwelveMonthTotalAmount(dto.getUserid()));

			dto.setMonthEntrustAmount(coreInvoiceAmountService.getUserMonthlyEntrustmentAmount(dto.getUserid()));
			dto.setQuarterEntrustAmount(coreInvoiceAmountService.getUserQuarterEntrustmentAmount(dto.getUserid()));
			dto.setYearEntrustAmount(coreInvoiceAmountService.getUserYearlyEntrustmentAmount(dto.getUserid()));
			dto.setTwelveMonthEntrustAmount(coreInvoiceAmountService.getUserTwelveMonthEntrustmentAmount(dto.getUserid()));

			dto.setInvoicingAmount(coreInvoiceAmountService.getUserInvoicingAmount(dto.getUserid()));
			dto.setQuarterStrategyAmount(coreInvoiceAmountService.getUserQuarterStrategyInvoicingAmount(dto.getUserid()));
			dto.setStrategyInvoiceAmount(invoiceMapper.getStrategyInvoiceAmount(dto.getUserid()));
			// 返回已绑定的支付主体返回过来（包括id，主体名称，是否测试过）
			dto.setIsvAgreementList(makerAlipayAgreementMapper.listByMakerid(dto.getUserid()));
		}
		return SmartResult.ofPage(page);
	}

	public SmartResult<MakerAlipayAvailableDto> listAvailableMakerAlipay(BaseSimpleFormBean<ListMakerAlipayFormBean> formBean) {
		@Valid ListMakerAlipayFormBean reqdata = formBean.getReqdata();
		Page<MakerAlipayAvailableDto> page = PageHelper.startPage(formBean.getPage(), formBean.getRows());
		reqdata.setMakerLabel(StringUtil.isEmpty(reqdata.getMakerLabel()) ? null : reqdata.getMakerLabel());
		reqdata.setProjectType(StringUtil.isEmpty(reqdata.getProjectType()) ? null : reqdata.getProjectType());

		List<MakerAlipayAvailableDto> list = makerAlipayMapper.listAvailableAlipay(reqdata.getPrincipalId(), reqdata.getCompname(),
				reqdata.getName(), reqdata.getMakerLabel(), reqdata.getProjectType(), reqdata.getFriendlyState(),
				reqdata.getInvoicescope(),
				reqdata.getFrom(), reqdata.getTo());
		// 查询创客项目总金额
		String entrustProjectStates = CalcAmountType.getEntrustProjectStates(CalcAmountType.PROCESSING);
		for (MakerAlipayAvailableDto dto : list) {
			dto.setMonthTotalAmount(coreInvoiceAmountService.getUserMonthlyTotalAmount(dto.getUserid()));
			dto.setQuarterTotalAmount(coreInvoiceAmountService.getUserQuarterTotalAmount(dto.getUserid()));
			dto.setYearTotalAmount(coreInvoiceAmountService.getUserYearlyTotalAmount(dto.getUserid()));
			dto.setTwelveMonthAmount(coreInvoiceAmountService.getUserTwelveMonthTotalAmount(dto.getUserid()));

			dto.setMonthEntrustAmount(coreInvoiceAmountService.getUserMonthlyEntrustmentAmount(dto.getUserid()));
			dto.setQuarterEntrustAmount(coreInvoiceAmountService.getUserQuarterEntrustmentAmount(dto.getUserid()));
			dto.setYearEntrustAmount(coreInvoiceAmountService.getUserYearlyEntrustmentAmount(dto.getUserid()));
			dto.setTwelveMonthEntrustAmount(coreInvoiceAmountService.getUserTwelveMonthEntrustmentAmount(dto.getUserid()));

			dto.setInvoicingAmount(coreInvoiceAmountService.getUserInvoicingAmount(dto.getUserid()));
			dto.setQuarterStrategyAmount(coreInvoiceAmountService.getUserQuarterStrategyInvoicingAmount(dto.getUserid()));
			dto.setStrategyInvoiceAmount(invoiceMapper.getStrategyInvoiceAmount(dto.getUserid()));
		}
		return SmartResult.ofPage(page);
	}

	public SmartResult<MakerAlipayPrincipalFlowDto> listPrincipalFlow(BaseSimpleFormBean<ListPrincipalFlowFormBean> formBean) {
		@Valid ListPrincipalFlowFormBean reqdata = formBean.getReqdata();
		Page<MakerAlipayPrincipalFlowDto> page = PageHelper.startPage(formBean.getPage(), formBean.getRows());
		makerAlipayPrincipalFlowMapper.list(reqdata.getName(),reqdata.getCompname(), reqdata.getType(), reqdata.getFrom(), reqdata.getTo());
		return SmartResult.ofPage(page);
	}

	public void testEntrusteePay(BaseSimpleFormBean<MakerPrincipalIdFormBean> formBean) {
		@Valid MakerPrincipalIdFormBean reqdata = formBean.getReqdata();
		int userid = reqdata.getUserid();
		int principalId = reqdata.getPrincipalId();
		BigDecimal amount = BigDecimal.valueOf(0.1);
		AlipayPrincipalEnum isvPrincipalEnum = getISVPrincipal();
		int isvId = isvPrincipalEnum.id;
		AlipayFundTransUniTransferResponse transferResponse = transfer2Entrustee(principalId, userid, amount);
		if (transferResponse == null || !transferResponse.isSuccess()) {
			log.info("测试受托人支付：从委托人主账户转账到创客记账本失败");
			throw SmartException.of(StatusMsg_240).setData(transferResponse);
		}

		log.info("测试受托人支付：从委托人主账户转账到创客记账本成功");
		AlipayFundTransUniTransferResponse payResponse = entrusteePay(0, userid, amount, "测试代付0.01元", AlipayIdentityEnum.LOGON_ID,
				"18602684069", "赵菲", null);
		// AlipayFundTransUniTransferResponse payResponse = entrusteePay(userid, amount, "测试代付0.1元", AlipayIdentityEnum.LOGON_ID,
		// 		"chenbob@outlook.com", "陈宝");
		if (payResponse == null || !payResponse.isSuccess()) {
			log.info("测试受托人支付：从受托人账户代付到客服支付宝账户失败");
			throw SmartException.of(StatusMsg_233).setData(payResponse);
		}
		log.info("测试受托人支付：从受托人账户代付到客服支付宝账户成功");
		makerAlipayAgreementMapper.testPassed(isvId, userid);
	}

	/**
	 * 创客与平台签约协议
	 *
	 * @param formBean
	 * @return
	 */
	public SmartResult userAgreementPageSign(BaseSimpleFormBean<MakerIsvIdFormBean> formBean) {
		int adminid = formBean.getUserid();
		@Valid MakerIsvIdFormBean reqdata = formBean.getReqdata();
		int userid = reqdata.getUserid();
		AlipayPrincipalEnum isvPrincipalEnum = getISVPrincipal();
		int isvId = isvPrincipalEnum.id;
		Asserts.notEquals(isvPrincipalEnum, AlipayPrincipalEnum.UNKOWN, StatusMsg_241);
		MakerStudio makerStudio = new MakerStudio().selectById(userid);
		Asserts.notNull(makerStudio, StatusMsg_228);
		MakerAlipayAgreement alipayAgreement = makerAlipayAgreementMapper.getByIsvIdAndUserid(isvId, userid);
		if (alipayAgreement != null) {
			// 判断签约状态
			AlipayAgreementStatusEnum status = AlipayAgreementStatusEnum.findById(alipayAgreement.getStatus());
			if (status == AlipayAgreementStatusEnum.NORMAL) {
				// 已签约，直接返回
				return SmartResult.fail(StatusMsg_234);
			}
		} else {
			alipayAgreement = new MakerAlipayAgreement();
			String agreementNo = RandomUtil.createRandomNo("ALI_SIGN_", "");
			alipayAgreement.setIsvId(isvId)
					.setUserid(userid)
					.setAdminId(adminid)
					.setAgreementNo(agreementNo)
					.setStatus(AlipayAgreementStatusEnum.TEMP.id)
					.insert();
		}

		String agreementResult = aliPayApiService.userAgreementPageSign(alipayAgreement.getAgreementNo(), isvPrincipalEnum);
		return SmartResult.success(agreementResult);
	}

	/**
	 * 创客与平台解约协议
	 *
	 * @param formBean
	 * @return
	 */
	public SmartResult userAgreementUnsign(BaseSimpleFormBean<MakerIsvIdFormBean> formBean) {
		int adminId = formBean.getUserid();
		@Valid MakerIsvIdFormBean reqdata = formBean.getReqdata();
		@Positive int userid = reqdata.getUserid();
		AlipayPrincipalEnum isvPrincipalEnum = getISVPrincipal();
		int isvId = isvPrincipalEnum.id;
		MakerAlipayAgreement alipayAgreement = makerAlipayAgreementMapper.getByIsvIdAndUserid(isvId, userid);
		Asserts.notNull(alipayAgreement, StatusMsg_101);

		if (aliPayApiService.userAgreementUnsign(alipayAgreement.getAgreementNo(), alipayAgreement.getAlipayAgreementNo(),
				isvPrincipalEnum)) {
			alipayAgreement.setStatus(AlipayAgreementStatusEnum.STOP.id).updateById();
			// 将资金记账本标记为废弃
		}

		return SmartResult.success();
	}

	/**
	 * 查询创客签约协议
	 *
	 * @param formBean
	 * @return
	 */
	public SmartResult userAgreementQuery(BaseSimpleFormBean<MakerIsvIdFormBean> formBean) {
		int adminId = formBean.getUserid();
		@Valid MakerIsvIdFormBean reqdata = formBean.getReqdata();
		@Positive int userid = reqdata.getUserid();
		AlipayPrincipalEnum isvPrincipalEnum = getISVPrincipal();
		int isvId = isvPrincipalEnum.id;
		MakerAlipayAgreement alipayAgreement = makerAlipayAgreementMapper.getByIsvIdAndUserid(isvId, userid);
		Asserts.notNull(alipayAgreement, StatusMsg_101);

		AlipayUserAgreementQueryResponse response = aliPayApiService.userAgreementQuery(alipayAgreement.getAgreementNo(),
				isvPrincipalEnum);
		if (response.isSuccess()) {
			alipayAgreement.setAlipayAgreementNo(response.getAgreementNo())
					.setPricipalType(response.getPricipalType())
					.setAlipayUserId(response.getPrincipalId())
					.setAlipayLogonId(response.getAlipayLogonId())
					.setSignScene(response.getSignScene())
					.setStatus(AlipayAgreementStatusEnum.findByCode(response.getStatus()).id)
					.setSignTime(DateUtil.parseDate(response.getSignTime(), DateUtil.FORMAT_STYLE_1))
					.setExternalLogonId(response.getExternalLogonId())
					.setValidTime(DateUtil.parseDate(response.getValidTime(), DateUtil.FORMAT_STYLE_1))
					.setAlipayLogonId(response.getAlipayLogonId());
			alipayAgreement.updateById();
			return SmartResult.success();
		} else {
			return SmartResult.fail();
		}
	}

	public SmartResult fundAccountBookCreate(BaseSimpleFormBean<MakerIsvIdFormBean> formBean) {
		@Valid MakerIsvIdFormBean reqdata = formBean.getReqdata();
		@Positive int userid = reqdata.getUserid();
		AlipayPrincipalEnum isvPrincipalEnum = getISVPrincipal();
		int isvId = isvPrincipalEnum.id;
		Asserts.notEquals(isvPrincipalEnum, AlipayPrincipalEnum.UNKOWN, StatusMsg_241);
		MakerAlipayAgreement alipayAgreement = makerAlipayAgreementMapper.getByIsvIdAndUserid(isvId, userid);
		Asserts.notNull(alipayAgreement, StatusMsg_233);
		if (!NumberUtil.equals(alipayAgreement.getStatus(), AlipayAgreementStatusEnum.NORMAL.id)) {
			// 签约状态不对， 返回
			return SmartResult.fail(StatusMsg_233);
		}
		MakerAlipayAccountBook makerAlipayAccountBook = createMakerAlipayAccountBook(alipayAgreement);
		if (makerAlipayAccountBook != null) return SmartResult.success(makerAlipayAccountBook);
		return SmartResult.fail();
	}

	private MakerAlipayAccountBook createMakerAlipayAccountBook(MakerAlipayAgreement alipayAgreement) {
		MakerAlipayAccountBook alipayAccountBook = makerAlipayAccountBookMapper.getByIsvIdAndUserid(alipayAgreement.getIsvId(),
				alipayAgreement.getUserid());
		Asserts.isNull(alipayAccountBook, StatusMsg_236);

		AlipayFundAccountbookCreateResponse response = aliPayApiService.fundAccountBookCreate(alipayAgreement.getAlipayUserId(),
				alipayAgreement.getAlipayAgreementNo(), getISVPrincipal());
		if (response != null && response.isSuccess()) {
			ExtCardInfo cardInfo = response.getExtCardInfo();
			alipayAccountBook = new MakerAlipayAccountBook().setUserid(alipayAgreement.getUserid())
					.setIsvId(alipayAgreement.getIsvId())
					.setAccountBookId(response.getAccountBookId())
					.setBankAccName(cardInfo.getBankAccName())
					.setCardBank(cardInfo.getCardBank())
					.setCardBranch(cardInfo.getCardBranch())
					.setCardDeposit(cardInfo.getCardDeposit())
					.setCardLocation(cardInfo.getCardLocation())
					.setCardNo(cardInfo.getCardNo())
					.setStatus(cardInfo.getStatus());
			alipayAccountBook.insert();
			return alipayAccountBook;
		}
		return null;
	}

	public SmartResult fundAccountBookQuery(BaseSimpleFormBean<MakerIsvIdFormBean> formBean) {
		@Valid MakerIsvIdFormBean reqdata = formBean.getReqdata();
		@Positive int userid = reqdata.getUserid();
		AlipayPrincipalEnum isvPrincipalEnum = getISVPrincipal();
		int isvId = isvPrincipalEnum.id;
		Asserts.notEquals(isvPrincipalEnum, AlipayPrincipalEnum.UNKOWN, StatusMsg_241);
		MakerAlipayAgreement alipayAgreement = makerAlipayAgreementMapper.getByIsvIdAndUserid(isvId, userid);
		MakerAlipayAccountBook alipayAccountBook = makerAlipayAccountBookMapper.getByIsvIdAndUserid(isvId, userid);
		Asserts.notNull(alipayAgreement, StatusMsg_233);
		// 签约状态不对， 返回
		Asserts.equals(alipayAgreement.getStatus(), AlipayAgreementStatusEnum.NORMAL.id, StatusMsg_233);
		if (queryAccountBook(alipayAgreement.getAlipayAgreementNo(), alipayAccountBook)) {
			return SmartResult.success(alipayAccountBook);
		}
		return SmartResult.fail();
	}

	public boolean queryAccountBook(String alipayAgreementNo, MakerAlipayAccountBook alipayAccountBook) {
		Asserts.notNull(alipayAccountBook, StatusMsg_233);
		AlipayPrincipalEnum isvPrincipalEnum = AlipayPrincipalEnum.findById(alipayAccountBook.getIsvId());
		String accountBookId = alipayAccountBook.getAccountBookId();
		AlipayFundAccountbookQueryResponse response = aliPayApiService.fundAccountBookQuery(accountBookId, alipayAgreementNo,
				isvPrincipalEnum);
		if (response != null && response.isSuccess()) {
			// 更新记账本信息， 包括可用余额
			ExtCardInfo cardInfo = response.getExtCardInfo();
			alipayAccountBook.setAvailableAmount(new BigDecimal(response.getAvailableAmount()))
					.setBankAccName(cardInfo.getBankAccName())
					.setCardBank(cardInfo.getCardBank())
					.setCardBranch(cardInfo.getCardBranch())
					.setCardDeposit(cardInfo.getCardDeposit())
					.setCardLocation(cardInfo.getCardLocation())
					.setCardNo(cardInfo.getCardNo())
					.setStatus(cardInfo.getStatus())
					.updateById();
			return true;
		}
		return false;
	}

	/**
	 * 给 平台委托人主账户的记账本充值
	 *
	 * @param formBean
	 * @return
	 */
	public SmartResult principalRecharge(BaseSimpleFormBean<AlipayPrincipalAccountRechargeFormBean> formBean) {
		// 委托方信息, 作为支付方
		@Valid AlipayPrincipalAccountRechargeFormBean reqdata = formBean.getReqdata();
		int principalId = reqdata.getPrincipalId();
		BigDecimal amount = reqdata.getAmount();

		AlipayPrincipalEnum isvPrincipalEnum = getISVPrincipal();
		MakerAlipayPrincipal alipayPrincipal = new MakerAlipayPrincipal().selectById(principalId);
		Asserts.notNull(alipayPrincipal, StatusMsg_241);
		// 签约状态不对， 返回
		Asserts.isTrue(StringUtil.equals(alipayPrincipal.getStatus(), AlipayAgreementStatusEnum.NORMAL.code), StatusMsg_242);

		// 新建订单信息
		String orderNo = RandomUtil.createRandomNo("REC_", "");
		MakerAlipayPrincipalOrder order = coreMakerAlipayService.createPrincipalOrder(isvPrincipalEnum.id, orderNo, alipayPrincipal)
				.setType(AlipayOrderEnum.PRINCIPAL_RECHARGE.type)
				.setPayeeAccountBookId(alipayPrincipal.getAccountBookId())
				.setPayeeAgreementNo(alipayPrincipal.getAlipayAgreementNo())
				.setPayeeAlipayUserId(alipayPrincipal.getAlipayUserId())
				.setAdminid(formBean.getUserid())
				.setAmount(amount)
				.setRemark("充值：" + amount)
				.setTitle("充值")
				.setState(AlipayOrderStatusEnum.CREATE.id);
		order.insert();

		RechargeModel rechargeModel = new RechargeModel().setAlipayUserId(alipayPrincipal.getAlipayUserId())
				.setAccountBookId(alipayPrincipal.getAccountBookId())
				.setAgreementNo(alipayPrincipal.getAlipayAgreementNo())
				.setOrderNo(orderNo)
				.setOrderTitle(order.getTitle())
				.setRemark(order.getRemark())
				.setTransAmount(amount);

		String response = aliPayApiService.fundTransPagePay(rechargeModel, isvPrincipalEnum);
		return SmartResult.success(response);
	}

	/**
	 * 从 平台委托人的主账户记账本转账到创客的记账本.
	 *
	 * @param principalId  委托人id
	 * @param targetUserId 目标受托人id(创客id)
	 * @param amount       金额
	 * @return
	 */
	public AlipayFundTransUniTransferResponse transfer2Entrustee(int principalId, int targetUserId, BigDecimal amount) {
		return coreMakerAlipayService.transfer2Entrustee(principalId, targetUserId, amount,0,0);
	}

	/**
	 * 从创客的记账本退款到 平台委托人的主账户记账本, 回退资金
	 *
	 * @param principalId 委托人主账户id
	 * @param fromUserid  从这个创客的资金记账本中退款
	 * @param amount
	 * @return
	 */
	public AlipayFundTransUniTransferResponse entrusteeRefund(int principalId, int fromUserid, BigDecimal amount) {
		AlipayPrincipalEnum isvPrincipalEnum = getISVPrincipal();
		int isvId = isvPrincipalEnum.id;
		// 委托方信息, 作为支付方
		AlipayPrincipalEnum alipayPrincipalEnum = AlipayPrincipalEnum.findById(principalId);
		Asserts.notEquals(alipayPrincipalEnum, AlipayPrincipalEnum.UNKOWN, StatusMsg_241);
		MakerAlipayPrincipal alipayPrincipal = new MakerAlipayPrincipal().selectById(alipayPrincipalEnum.id);

		MakerAlipayAgreement fromAlipayAgreement = makerAlipayAgreementMapper.getByIsvIdAndUserid(isvId, fromUserid);
		Asserts.notNull(fromAlipayAgreement, StatusMsg_233);
		MakerAlipayAccountBook fromAlipayAccountBook = makerAlipayAccountBookMapper.getByIsvIdAndUserid(isvId, fromUserid);
		Asserts.notNull(fromAlipayAccountBook, StatusMsg_233);

		// 创建转账订单
		String orderNo = RandomUtil.createRandomNo("REFUND_", "");
		MakerAlipayPrincipalOrder order = new MakerAlipayPrincipalOrder().setIsvId(isvId)
																		 .setOrderNo(orderNo)
																		 .setAccountBookId(fromAlipayAccountBook.getAccountBookId())
																		 .setPrincipalId(principalId)
																		 .setType(AlipayOrderEnum.ENTRUSTEE_REFUND.type)
																		 .setPayeeEntrusteeId(AlipayIdentityEnum.ACCOUNT_BOOK_ID.id)
																	     .setPayeeAccountBookId(alipayPrincipal.getAccountBookId())
																	     .setPayeeAgreementNo(alipayPrincipal.getAlipayAgreementNo())
																	     .setAmount(amount)
																	     .setRemark("从创客记账本【" + fromAlipayAccountBook.getAccountBookId() + "】退回到主账户")
																	     .setTitle("退款")
																	     .setState(AlipayOrderStatusEnum.CREATE.id);
		order.insert();

		// 订单支付信息
		TransferModel model = new TransferModel();
		model.setOrderNo(orderNo);
		model.setOrderTitle("退款");
		model.setOrderRemark("金额：" + amount + "元");
		model.setTransAmount(amount);
		// 付款方信息, 基于记账本
		model.setAccountBookId(fromAlipayAccountBook.getAccountBookId());
		model.setAlipayAgreementNo(fromAlipayAgreement.getAlipayAgreementNo());
		// 收款方信息
		TransferModel.PayeeInfo payeeInfo = TransferModel.PayeeInfo.of(AlipayIdentityEnum.ACCOUNT_BOOK_ID,
				alipayPrincipal.getAccountBookId(), "", alipayPrincipal.getAlipayAgreementNo());
		model.setPayeeInfo(payeeInfo);
		AlipayFundTransUniTransferResponse response = aliPayApiService.fundTransUniTransferAllocation(model, isvPrincipalEnum);
		return response;
	}

	/**
	 * 从创客的资金记账本代付给自然人的个人支付宝账号/个人银行卡
	 *
	 * @param projectId     订单项目id- 委托接单子项目id
	 * @param entrusteeId   受托人id
	 * @param amount        代付金额,单位元,2位小数
	 * @param orderTitle    订单标题
	 * @param identityEnum  收款人身份标识，支持支付宝账号或者参考个人银行卡 {@link AlipayIdentityEnum}
	 * @param payeeIdentity 支付宝账号或银行卡号
	 * @param payeeName     收款人姓名或账户名
	 * @param doAfterPay    支付请求发送成功后的后续步骤
	 * @return
	 */
	public AlipayFundTransUniTransferResponse entrusteePay(int projectId, int entrusteeId, BigDecimal amount, String orderTitle,
	                                                       AlipayIdentityEnum identityEnum, String payeeIdentity, String payeeName,
	                                                       BiConsumer<MakerAlipayAccountOrder, AlipayFundTransUniTransferResponse> doAfterPay) {
		AlipayPrincipalEnum isvPrincipalEnum = getISVPrincipal();
		int isvId = isvPrincipalEnum.id;
		MakerAlipayAgreement alipayAgreement = makerAlipayAgreementMapper.getByIsvIdAndUserid(isvId, entrusteeId);
		Asserts.notNull(alipayAgreement, StatusMsg_233);
		MakerAlipayAccountBook alipayAccountBook = makerAlipayAccountBookMapper.getByIsvIdAndUserid(isvId, entrusteeId);
		Asserts.notNull(alipayAccountBook, StatusMsg_233);

		// 新建订单支付信息
		String orderNo = RandomUtil.createRandomNo("ENT_PAY_", "");
		String remark = "项目款：" + amount + "元";
		MakerAlipayAccountOrder order = new MakerAlipayAccountOrder().setIsvId(isvPrincipalEnum.id)
				.setOrderNo(orderNo)
				.setEntrusteeId(entrusteeId)
				.setAccountBookId(alipayAccountBook.getAccountBookId())
				.setType(AlipayOrderEnum.ENTRUSTEE_PAY.type)
				.setProjectId(projectId)
				.setAmount(amount)
				.setTitle(orderTitle)
				.setRemark(remark)
				.setPayeeType(identityEnum.id)
				.setPayeeId(payeeIdentity)
				.setPayeeName(payeeName)
				.setState(AlipayOrderStatusEnum.CREATE.id);
		order.insert();

		TransferModel model = new TransferModel();
		model.setOrderNo(orderNo);
		model.setOrderTitle(orderTitle);
		// model.setOrderRemark(remark);
		model.setTransAmount(amount);
		// 付款方信息, 基于记账本
		model.setAccountBookId(alipayAccountBook.getAccountBookId());
		model.setAlipayAgreementNo(alipayAgreement.getAlipayAgreementNo());
		// 收款方信息
		TransferModel.PayeeInfo payeeInfo = TransferModel.PayeeInfo.of(identityEnum, payeeIdentity, payeeName, "");
		model.setPayeeInfo(payeeInfo);
		AlipayFundTransUniTransferResponse response = aliPayApiService.fundTransUniTransfer(model, isvPrincipalEnum);
		if (response == null) {
			return response;
		} else if (response.isSuccess()) {
			order.setAlipayOrderNo(response.getOrderId()).setAlipayPayFundOrderId(response.getPayFundOrderId()).updateById();
		} else {
			order.setAlipayErrorCode(response.getSubCode()).setAlipayErrorMsg(response.getSubMsg()).updateById();
		}

		// 处理后续业务
		if (doAfterPay != null) {
			doAfterPay.accept(order, response);
		}
		return response;
	}

	/**
	 * 将支付主体的资金记账本中的钱 转到 企业公户银行卡中
	 *
	 * @param formBean
	 * @return
	 */
	public SmartResult<AlipayFundTransUniTransferResponse> principalPay2PublicBankAccount(
			BaseSimpleFormBean<PrincipalPayPublicAccountFormBean> formBean) {
		PrincipalPayPublicAccountFormBean reqdata = formBean.getReqdata();
		int principalId = reqdata.getPrincipalId();
		String accountNo = reqdata.getAccountNo();
		BigDecimal amount = reqdata.getAmount();
		String remark = reqdata.getRemark();
		String name = reqdata.getName();
		String bankCode = reqdata.getBankCode();
		String instName = reqdata.getInstName();
		String instBranchName = reqdata.getInstBranchName();

		AlipayPrincipalEnum isvPrincipalEnum = getISVPrincipal();
		int isvId = isvPrincipalEnum.id;
		// 委托方信息, 作为支付方
		AlipayPrincipalEnum alipayPrincipalEnum = AlipayPrincipalEnum.findById(principalId);
		Asserts.notEquals(alipayPrincipalEnum, AlipayPrincipalEnum.UNKOWN, StatusMsg_241);
		MakerAlipayPrincipal alipayPrincipal = new MakerAlipayPrincipal().selectById(alipayPrincipalEnum.id);

		// 创建转账订单
		String orderNo = RandomUtil.createRandomNo("TRANS_", "");
		String title = "转账给【" + name + "】企业公户";
		MakerAlipayPrincipalOrder order = new MakerAlipayPrincipalOrder().setIsvId(isvId)
				.setOrderNo(orderNo)
				.setAccountBookId(alipayPrincipal.getAccountBookId())
				.setPrincipalId(alipayPrincipal.getId())
				.setType(AlipayOrderEnum.PRINCIPAL_TRANSFER_PUBLIC_BANK.type)
				.setPayeeEntrusteeId(null)
				.setAmount(amount)
				.setTitle(title)
				.setRemark(remark)
				.setState(AlipayOrderStatusEnum.CREATE.id);
		order.insert();

		TransferModel model = new TransferModel();
		model.setOrderNo(orderNo);
		model.setOrderTitle(title);
		// model.setOrderRemark(remark);
		model.setTransAmount(amount);
		// 付款方信息, 基于记账本
		model.setAccountBookId(alipayPrincipal.getAccountBookId());
		model.setAlipayAgreementNo(alipayPrincipal.getAlipayAgreementNo());
		// 收款方信息
		TransferModel.PayeeInfo payeeInfo = TransferModel.PayeeInfo.ofPublicBankAcct(accountNo, name, bankCode, instName, instBranchName);
		model.setPayeeInfo(payeeInfo);
		AlipayFundTransUniTransferResponse response = aliPayApiService.fundTransUniTransfer(model, isvPrincipalEnum);
		if (response == null) {
			return SmartResult.fail();
		} else if (response.isSuccess()) {
			order.setAlipayOrderNo(response.getOrderId()).setAlipayPayFundOrderId(response.getPayFundOrderId());
		} else {
			order.setAlipayErrorCode(response.getSubCode()).setAlipayErrorMsg(response.getSubMsg()).updateById();
		}

		return SmartResult.success(response);
	}

	/**
	 * 将支付主体的资金记账本中的钱 转到 指定委托主体的企业公户
	 *
	 * @param formBean
	 * @return
	 */
	public SmartResult<AlipayFundTransUniTransferResponse> principalTransferPrincipalPublicBankAccount(
			BaseSimpleFormBean<PrincipalTransferPrincipalPublicAccountFormBean> formBean) {
		PrincipalTransferPrincipalPublicAccountFormBean reqdata = formBean.getReqdata();
		int principalId = reqdata.getPrincipalId();
		int payeePrincipalId = reqdata.getPayeePrincipalId();
		BigDecimal amount = reqdata.getAmount();
		String remark = reqdata.getRemark();

		Asserts.notTrue(principalId == payeePrincipalId, StatusMsg_263);

		AlipayPrincipalEnum isvPrincipalEnum = getISVPrincipal();
		int isvId = isvPrincipalEnum.id;
		// 委托方信息, 作为支付方
		AlipayPrincipalEnum alipayPrincipalEnum = AlipayPrincipalEnum.findById(principalId);
		Asserts.notEquals(alipayPrincipalEnum, AlipayPrincipalEnum.UNKOWN, StatusMsg_241);
		MakerAlipayPrincipal alipayPrincipal = new MakerAlipayPrincipal().selectById(alipayPrincipalEnum.id);

		// 委托方信息, 作为收款方
		AlipayPrincipalEnum payeePrincipalEnum = AlipayPrincipalEnum.findById(payeePrincipalId);
		Asserts.notEquals(payeePrincipalEnum, AlipayPrincipalEnum.UNKOWN, StatusMsg_241);
		MakerAlipayPrincipal payeePrincipal = new MakerAlipayPrincipal().selectById(payeePrincipalEnum.id);

		String publicAcctNo = payeePrincipal.getPublicAcctNo();
		String publicAcctName = payeePrincipal.getPublicAcctName();
		String publicInstName = payeePrincipal.getPublicInstName();
		String publicInstBranchName = payeePrincipal.getPublicInstBranchName();
		String publicBankCode = payeePrincipal.getPublicBankCode();
		Asserts.notAnyEmpty(StatusMsg_262, publicAcctNo, publicAcctName, publicInstName);

		// 创建转账订单
		String orderNo = RandomUtil.createRandomNo("TRANS_", "");
		String title = "转账给【" + publicAcctName + "】企业公户";
		MakerAlipayPrincipalOrder order = new MakerAlipayPrincipalOrder().setIsvId(isvId)
				.setOrderNo(orderNo)
				.setAccountBookId(alipayPrincipal.getAccountBookId())
				.setPrincipalId(alipayPrincipal.getId())
				.setType(AlipayOrderEnum.PRINCIPAL_TRANSFER_PUBLIC_BANK.type)
				.setPayeeEntrusteeId(null)
				.setAmount(amount)
				.setTitle(title)
				.setRemark(title + "。" + remark)
				.setState(AlipayOrderStatusEnum.CREATE.id);
		order.insert();

		TransferModel model = new TransferModel();
		model.setOrderNo(orderNo);
		model.setOrderTitle(title);
		// model.setOrderRemark(remark);
		model.setTransAmount(amount);
		// 付款方信息, 基于记账本
		model.setAccountBookId(alipayPrincipal.getAccountBookId());
		model.setAlipayAgreementNo(alipayPrincipal.getAlipayAgreementNo());
		// 收款方信息
		TransferModel.PayeeInfo payeeInfo = TransferModel.PayeeInfo.ofPublicBankAcct(publicAcctNo, publicAcctName, publicBankCode,
				publicInstName, publicInstBranchName);
		model.setPayeeInfo(payeeInfo);
		AlipayFundTransUniTransferResponse response = aliPayApiService.fundTransUniTransfer(model, isvPrincipalEnum);
		if (response == null) {
			return SmartResult.fail();
		} else if (response.isSuccess()) {
			order.setAlipayOrderNo(response.getOrderId()).setAlipayPayFundOrderId(response.getPayFundOrderId());
		} else {
			order.setAlipayErrorCode(response.getSubCode()).setAlipayErrorMsg(response.getSubMsg()).updateById();
		}

		return SmartResult.success(response);
	}

	/** 重新支付-指定已经失败的项目id */
	public void entrusteeRepay(int projectId) {
		EntrustmentProjectItem item = new EntrustmentProjectItem().selectById(projectId);
		Asserts.notNull(item, StatusMsg.StatusMSG_1101);
		Asserts.isTrue(item.getState() == EntrustProjectState.FAIL, StatusMsg.StatusMsg_1105);
		Asserts.isTrue(item.getEntrustState() == EntrustState.RECEIVED, StatusMsg.StatusMsg_1106);
		AlipayIdentityEnum identityEnum = item.getAccountType() == 1 ? AlipayIdentityEnum.LOGON_ID : AlipayIdentityEnum.BANKCARD_ACCOUNT;

		// 目前仅支持受托人创客代付到自然人的支付宝账号或银行卡时,支付失败,才能进行重新支付
		MakerAlipayAccountOrder order = makerAlipayAccountOrderMapper.getOrderByprojectId(projectId);
		Asserts.notNull(order, StatusMsg.StatusMsg_1108);

		// 执行受托人支付操作, 调用回调方法doAfterEntrustmentProjectPay,处理后续步骤
		item.setState(EntrustProjectState.DISPATCHED).updateById();
		entrusteePay(item.getId(), item.getEntrusteeId(), item.getAmount(), item.getName(), identityEnum, item.getAccountNo(),
				item.getPayeeName(), (accountOrder, response) -> doAfterEntrustmentProjectPay(item, accountOrder, response));

		// 修改状态
		order.setRepay(Constants.TRUE).updateById();
	}

	public SmartResult fundTransOrderQuery(int bizType, String oderNo) {
		AlipayFundTransCommonQueryResponse response = aliPayApiService.fundTransCommonQuery(AlipayOrderEnum.findById(bizType), oderNo,
				getISVPrincipal());
		return SmartResult.success(response);
	}

	/**
	 * 企业安全发签约结果通知回调
	 *
	 * @return
	 */
	public String userAgreementSignNotify(HttpServletRequest request) {
		Map<String, String> params = convertRequestParamsToMap(request); // 将异步通知中收到的待验证所有参数都存放到map中
		log.info("回调paramPairs={}", JSON.toJSONString(params));
		AlipayUserAgreementPageSingNotifyModel model = JSON.parseObject(JSON.toJSONString(params),
				AlipayUserAgreementPageSingNotifyModel.class);
		String externalAgreementNo = model.getExternal_agreement_no();
		MakerAlipayAgreement alipayAgreement = new MakerAlipayAgreement().selectOne(
				Condition.create().eq("agreement_no", externalAgreementNo));
		MakerAlipayPrincipal alipayPrincipal = new MakerAlipayPrincipal().selectOne(
				Condition.create().eq("agreement_no", externalAgreementNo));
		if (alipayAgreement != null) {
			// 创客签约
			log.info("创客签约 externalAgreementNo = {}", externalAgreementNo);
			if (checkSign(params, alipayAgreement.getIsvId())) {
				alipayAgreement.setAlipayAgreementNo(model.getAgreement_no())
						.setAlipayLogonId(model.getAlipay_logon_id())
						.setAppId(model.getApp_id())
						.setSignScene(model.getSign_scene())
						.setStatus(AlipayAgreementStatusEnum.findByCode(model.getStatus()).id)
						.setAlipayUserId(model.getAlipay_user_id())
						.setSignTime(DateUtil.parseDate(model.getSign_time(), DateUtil.FORMAT_STYLE_1))
						.setExternalLogonId(model.getExternal_logon_id())
						.setAuthAppId(model.getAuth_app_id())
						.setValidTime(DateUtil.parseDate(model.getValid_time(), DateUtil.FORMAT_STYLE_1))
						.setAlipayLogonId(model.getAlipay_logon_id())
						.updateById();
				// 异步创建资金记账本, 如果已经存在记账本, 则不会新建, 直接使用原来的记账本
				executor.submit(() -> createMakerAlipayAccountBook(alipayAgreement));
				return "success";
			} else {
				log.info("支付宝回调签名认证失败，signVerified=false, paramsJson");
				return "failure";
			}
		} else if (alipayPrincipal != null) {
			//  平台主体账户的签约
			log.info(" 平台主体账户的签约 externalAgreementNo = {}", externalAgreementNo);
			if (checkSign(params, alipayPrincipal.getIsvId())) {
				alipayPrincipal.setAlipayAgreementNo(model.getAgreement_no())
						.setAlipayLogonId(model.getAlipay_logon_id())
						.setSignScene(model.getSign_scene())
						.setStatus(model.getStatus())
						.setAlipayUserId(model.getAlipay_user_id())
						.setSignTime(DateUtil.parseDate(model.getSign_time(), DateUtil.FORMAT_STYLE_1))
						.setValidTime(DateUtil.parseDate(model.getValid_time(), DateUtil.FORMAT_STYLE_1))
						.setAlipayLogonId(model.getAlipay_logon_id())
						.updateById();
				// 异步创建资金记账本, 如果已经存在记账本, 则不会新建, 直接使用原来的记账本
				executor.submit(() -> createZddPrincipalAccount(alipayPrincipal));
				return "success";
			} else {
				log.info("支付宝回调签名认证失败，signVerified=false, paramsJson");
				return "failure";
			}
		} else {
			log.info(" 平台没有此签约记录.");
			return "failure";
		}
	}

	/**
	 * @param params
	 * @param isvId  签约主体ISV id
	 * @return
	 */
	private boolean checkSign(Map<String, String> params, Integer isvId) {
		BaseAlipayConfig alipayConfig = ContextUtil.getBean(AlipayPrincipalEnum.findById(isvId).config);
		try {
			return AlipaySignature.certVerifyV1(params, alipayConfig.getAlipayCertPublicKeyPath(), alipayConfig.getAlipayCharset(),
					alipayConfig.getAlipaySignType());
		} catch (AlipayApiException e) {
			log.error("支付宝回调, 验签失败", e);
		}
		return false;
	}

	public String transOrderChangedNotify(HttpServletRequest request) {
		log.info("queryString={}", request.getQueryString());
		Map<String, String> params = convertRequestParamsToMap(request); // 将异步通知中收到的待验证所有参数都存放到map中
		String paramsJson = JSON.toJSONString(params);
		return null;
	}

	/**
	 * 将request中的参数转换成Map
	 */
	private static Map<String, String> convertRequestParamsToMap(HttpServletRequest request) {
		Map<String, String> params = new HashMap<String, String>();
		Map requestParams = request.getParameterMap();
		for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext(); ) {
			String name = (String) iter.next();
			String[] values = (String[]) requestParams.get(name);
			String valueStr = "";
			for (int i = 0; i < values.length; i++) {
				valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
			}
			params.put(name, valueStr);
		}
		return params;
	}

	// ********************************** 定时任务, 处理项目支付流程 ********************************//

	public void refreshMakerAlipayAccountBook() {
		for (MakerAlipayAccountBook alipayAccountBook : new MakerAlipayAccountBook().selectAll()) {
			try {
				MakerAlipayAgreement agreement = makerAlipayAgreementMapper.getByIsvIdAndUserid(alipayAccountBook.getIsvId(),
						alipayAccountBook.getUserid());
				if (agreement.getStatus() != AlipayAgreementStatusEnum.NORMAL.id) continue;
				queryAccountBook(agreement.getAlipayAgreementNo(), alipayAccountBook);
			} catch (Exception e) {
				log.error("刷新绑定了企业支付宝的创客资金记账本报错, userid={}", alipayAccountBook.getUserid(), e);
			}
		}
	}

	public void refreshAlipayPrincipalRecharge() {
		ArrayList<Integer> processingStatus = Lists.newArrayList(AlipayOrderStatusEnum.CREATE.id, AlipayOrderStatusEnum.WAIT_PAY.id,
				AlipayOrderStatusEnum.DEALING.id);
		List<MakerAlipayPrincipalOrder> list = makerAlipayPrincipalOrderMapper.listByStatus(processingStatus,
				AlipayOrderEnum.PRINCIPAL_RECHARGE.type);
		for (MakerAlipayPrincipalOrder order : list) {
			try {
				String orderNo = order.getOrderNo();
				AlipayPrincipalEnum isvPrincipalEnum = AlipayPrincipalEnum.findById(order.getIsvId());
				AlipayFundTransCommonQueryResponse response = aliPayApiService.fundTransCommonQuery(AlipayOrderEnum.PRINCIPAL_RECHARGE,
						orderNo, isvPrincipalEnum);
				// 处理查询结果
				coreMakerAlipayService.handlePrincipalOrderQueryResponse(order, response, this::handlePrincipalRechargeSuccess);

			} catch (Exception e) {
				log.error("刷新 平台委托人主体记账本充值报错, orderNo={}", order.getOrderNo(), e);
			}
		}
	}

	/**
	 * 定时刷新委托人转账给受托人创客记账本的订单信息
	 */
	public void refreshAlipayPrincipalTransfer() {
		ArrayList<Integer> processingStatus = Lists.newArrayList(AlipayOrderStatusEnum.CREATE.id, AlipayOrderStatusEnum.WAIT_PAY.id,
				AlipayOrderStatusEnum.DEALING.id);
		// 获取1:创建 3:等待支付 6:处理中 的订单id
		List<Integer> ids = makerAlipayPrincipalOrderMapper.listProcessingOrderIds(
				StringUtils.joinWith(",", AlipayOrderEnum.PRINCIPAL_TRANSFER.type, AlipayOrderEnum.PRINCIPAL_TRANSFER_PUBLIC_BANK.type));
		for (Integer orderid : ids) {
			MakerAlipayPrincipalOrder order = new MakerAlipayPrincipalOrder().selectById(orderid);
			try {
				// 再次判断状态, 防止其他线程同时处理这个订单.
				if (processingStatus.contains(order.getState())) {
					if (order.getType() == AlipayOrderEnum.PRINCIPAL_TRANSFER_PUBLIC_BANK.type) {
						AlipayFundTransCommonQueryResponse response = aliPayApiService.fundTransCommonQuery(
								AlipayOrderEnum.PRINCIPAL_TRANSFER_PUBLIC_BANK, order.getOrderNo(), getISVPrincipal());
						// 处理查询结果
						coreMakerAlipayService.handlePrincipalOrderQueryResponse(order, response, this::recordPrincipalTransfeFlow);
					} else if (order.getType() == AlipayOrderEnum.PRINCIPAL_TRANSFER.type) {
						AlipayFundTransCommonQueryResponse response = aliPayApiService.fundTransCommonQuery(
								AlipayOrderEnum.PRINCIPAL_TRANSFER, order.getOrderNo(), getISVPrincipal());
						// 处理查询结果
						coreMakerAlipayService.handlePrincipalOrderQueryResponse(order, response, this::handlePrincipalTransferSuccess);
						//委托接单项目发送失败通知
						if(order.getState() != 2){
							coreEntrustProjectServcie.handleTransferFailed(order.getProjectId());
						}
					} else if(order.getType() == AlipayOrderEnum.ENTRUSTEE_REFUND.type) {
						AlipayFundTransCommonQueryResponse response = aliPayApiService.fundTransCommonQuery(
								AlipayOrderEnum.ENTRUSTEE_REFUND, order.getOrderNo(), getISVPrincipal());
						// 处理查询结果
						coreMakerAlipayService.handlePrincipalOrderQueryResponse(order, response, this::recordPrincipalRefundTransFlow);

					}
				}

			} catch (Exception e) {
				log.error("定时刷新委托人转账给受托人创客记账本的订单信息报错, orderNo={}", order.getOrderNo(), e);
			}
		}
	}

	/**
	 * 定时刷新受托人代付给自然人账户的订单信息
	 */
	public void refreshAlipayEntrusteePay() {
		ArrayList<Integer> processingStatus = Lists.newArrayList(AlipayOrderStatusEnum.CREATE.id, AlipayOrderStatusEnum.WAIT_PAY.id,
				AlipayOrderStatusEnum.DEALING.id);
		List<Integer> ids = makerAlipayAccountOrderMapper.listProcessingOrderIds(AlipayOrderEnum.ENTRUSTEE_PAY.type);
		for (Integer orderid : ids) {
			MakerAlipayAccountOrder order = new MakerAlipayAccountOrder().selectById(orderid);
			try {
				// 再次判断状态, 防止其他线程同时处理这个订单.
				if (processingStatus.contains(order.getState())) {
					AlipayFundTransCommonQueryResponse response = aliPayApiService.fundTransCommonQuery(AlipayOrderEnum.ENTRUSTEE_PAY,
							order.getOrderNo(), getISVPrincipal());
					// 处理查询结果
					handleEntrusteeOrderQueryResponse(order, response);
					//委托接单项目发送失败通知
					if(order.getState() != 2){
						coreEntrustProjectServcie.handleTransferFailed(order.getProjectId());
					}
				}
			} catch (Exception e) {
				log.error("定时刷新受托人代付给自然人账户的订单信息报错, orderNo={}", order.getOrderNo(), e);
			}
		}
	}

	private void handleEntrusteeOrderQueryResponse(MakerAlipayAccountOrder order, AlipayFundTransCommonQueryResponse response) {
		if (response == null) {
			log.info("查询受托人代付给自然人订单状态, response为null, orderNo={}", order.getOrderNo());
			return;
		}
		if (response.isSuccess()) {
			AlipayOrderStatusEnum statusEnum = AlipayOrderStatusEnum.findByCode(response.getStatus());
			// 设置状态
			order.setState(statusEnum.id).setAlipayStatus(response.getStatus()).setAlipayMsg(response.getMsg());
			switch (statusEnum) {
				case SUCCESS:
					order.setAlipayOrderNo(response.getOrderId())
							.setAlipayPayFundOrderId(response.getPayFundOrderId())
							.setFinishTime(DateUtil.parseDate(response.getPayDate(), DateUtil.FORMAT_STYLE_1))
							.updateById();
					handleEntrusteePaySuccess(order);
					break;
				case DEALING:
					order.setAlipayOrderNo(response.getOrderId()).updateById();
					break;
				case CLOSED:
				case FAIL:
				case REFUND:
				case UNKOWN:
					order.setFinishTime(new Date()).updateById();
					handleEntrusteePayFailed(order);
					break;
				default:
					order.updateById();
					break;
			}
		} else {
			// 查询失败,设置失败原因
			order.setState(AlipayOrderStatusEnum.FAIL.id)
					.setAlipayStatus(response.getStatus())
					.setAlipayMsg(response.getMsg())
					.setAlipayErrorCode(response.getSubCode())
					.setAlipayErrorMsg(response.getSubMsg() + response.getFailReason())
					.updateById();
		}

	}

	private void handlePrincipalRechargeSuccess(MakerAlipayPrincipalOrder order) {
		// 记录充值流水
		MakerAlipayPrincipal alipayPrincipal = new MakerAlipayPrincipal().selectById(order.getPrincipalId());
		BigDecimal amount = order.getAmount();
		BigDecimal prevAmount = alipayPrincipal.getAvailableAmount();
		BigDecimal fronzenAmount = alipayPrincipal.getFrozenAmount();
		MakerAlipayPrincipalFlow flow = new MakerAlipayPrincipalFlow().setOrderNo(order.getOrderNo())
				.setPrincipalId(order.getPrincipalId())
				.setAccountBookId(order.getAccountBookId())
				.setType(AlipayPrincipalAccountFlowType.RECHARGE)
				.setAmount(amount)
				.setPrevAmount(prevAmount)
				.setAfterAmount(prevAmount.add(amount))
				.setPrevFrozenAmount(fronzenAmount)
				.setAfterFrozenAmount(fronzenAmount)
				.setRemark(order.getRemark())
				.setFlowTime(order.getFinishTime());
		flow.insert();
		// 重新刷新下记账本信息
		coreMakerAlipayService.queryZddPrincipalAccount(alipayPrincipal.getId());

	}

	/**
	 * 处理 委托人主体转账给 受托人(创客) 成功后的逻辑
	 *
	 * @param order
	 */
	private void handlePrincipalTransferSuccess(MakerAlipayPrincipalOrder order) {
		AlipayPrincipalEnum isvPrincipalEnum = getISVPrincipal();
		int isvId = isvPrincipalEnum.id;
		// 记录委托主体账户流水
		recordPrincipalTransfeFlow(order);

		// 记录受托人创客的流水
		BigDecimal amount = order.getAmount();
		Integer payeeEntrusteeId = order.getPayeeEntrusteeId();
		MakerAlipayAgreement alipayAgreement = makerAlipayAgreementMapper.getByIsvIdAndUserid(isvId, payeeEntrusteeId);
		MakerAlipayAccountBook alipayAccountBook = makerAlipayAccountBookMapper.getByIsvIdAndUserid(isvId, payeeEntrusteeId);
		BigDecimal entrusteePrevAmount = alipayAccountBook.getAvailableAmount();
		MakerAlipayAccountFlow entrusteeFlow = new MakerAlipayAccountFlow().setOrderNo(order.getOrderNo())
				.setEntrusteeId(payeeEntrusteeId)
				.setAccountBookId(order.getPayeeAccountBookId())
				.setType(AlipayMakerAccountFlowType.TRANSFER)
				.setAmount(amount)
				.setPrevAmount(entrusteePrevAmount)
				.setAfterAmount(entrusteePrevAmount.add(amount))
				.setRemark(order.getRemark())
				.setFlowTime(order.getFinishTime());
		entrusteeFlow.insert();
		// 重新刷新下记账本信息
		queryAccountBook(alipayAgreement.getAlipayAgreementNo(), alipayAccountBook);

		// 处理下一步,通过转账订单号和受托人id,找到所有的委托项目,进行代付
		handleEntrustmentProjectPay(order);

	}

	private void recordPrincipalTransfeFlow(MakerAlipayPrincipalOrder order) {
		// 转账成功，解冻被冻结的金额
		Integer principalId = order.getPrincipalId();
		BigDecimal amount = order.getAmount();
		MakerAlipayPrincipal alipayPrincipal = new MakerAlipayPrincipal().selectById(principalId);
		BigDecimal prevFronzenAmount = alipayPrincipal.getFrozenAmount();
		coreMakerAlipayService.unfrozonPrincipalAmount(principalId, amount);
		// 重新获取新的冻结金额
		BigDecimal afterFrozenAmount = new MakerAlipayPrincipal().selectById(principalId).getFrozenAmount();
		// 记录调拨转账流水
		BigDecimal prevAmount = alipayPrincipal.getAvailableAmount();
		int type = AlipayPrincipalAccountFlowType.TRANSFER;
		if (NumberUtil.equals(order.getType(), AlipayOrderEnum.PRINCIPAL_TRANSFER_PUBLIC_BANK.type)) {
			type = AlipayPrincipalAccountFlowType.TRANSFER_PRINCIPAL_BANK;
		}
		MakerAlipayPrincipalFlow principalFlow = new MakerAlipayPrincipalFlow().setOrderNo(order.getOrderNo())
				.setPrincipalId(principalId)
				.setAccountBookId(order.getAccountBookId())
				.setType(type)
				.setAmount(amount)
				.setPrevAmount(prevAmount)
				.setAfterAmount(prevAmount.subtract(amount))
				.setPrevFrozenAmount(prevFronzenAmount)
				.setAfterFrozenAmount(afterFrozenAmount)
				.setRemark(order.getRemark())
				.setFlowTime(order.getFinishTime());
		principalFlow.insert();
		// 重新刷新下记账本信息
		coreMakerAlipayService.queryZddPrincipalAccount(alipayPrincipal.getId());
	}

	private void recordPrincipalRefundTransFlow(MakerAlipayPrincipalOrder order) {
		// 转账成功
		Integer principalId = order.getPrincipalId();
		BigDecimal amount = order.getAmount();
		MakerAlipayPrincipal alipayPrincipal = new MakerAlipayPrincipal().selectById(principalId);
		// 记录调拨转账流水
		BigDecimal prevAmount = alipayPrincipal.getAvailableAmount();
		MakerAlipayPrincipalFlow principalFlow = new MakerAlipayPrincipalFlow().setOrderNo(order.getOrderNo())
				.setPrincipalId(principalId)
				.setAccountBookId(order.getAccountBookId())
				.setType(order.getType())
				.setAmount(amount)
				.setPrevAmount(prevAmount)
				.setAfterAmount(prevAmount.add(amount))
				.setPrevFrozenAmount(alipayPrincipal.getFrozenAmount())
				.setAfterFrozenAmount(alipayPrincipal.getFrozenAmount())
				.setRemark(order.getRemark())
				.setFlowTime(order.getFinishTime());
		principalFlow.insert();
		// 重新刷新下记账本信息
		coreMakerAlipayService.queryZddPrincipalAccount(alipayPrincipal.getId());
	}

	private void handleEntrusteePaySuccess(MakerAlipayAccountOrder order) {
		// 处理项目状态
		String orderNo = order.getOrderNo();
		EntrustmentProjectItem projectItem = new EntrustmentProjectItem().selectOne(Condition.create().eq("pay_no", orderNo));
		if (projectItem != null) {
			projectItem.setFinishTime(order.getFinishTime())
					.setState(EntrustProjectState.FINISH)
					.setEntrustState(EntrustState.FINISH)
					.updateById();
			coreEntrustProjectServcie.refreshProjectStatus(projectItem.getImportId());
		}

		// 记录受托人创客的流水
		Integer payeeEntrusteeId = order.getEntrusteeId();
		MakerAlipayAccountBook alipayAccountBook = makerAlipayAccountBookMapper.getByAccountBookId(order.getAccountBookId());
		MakerAlipayAgreement alipayAgreement = makerAlipayAgreementMapper.getByIsvIdAndUserid(order.getIsvId(), payeeEntrusteeId);
		BigDecimal entrusteePrevAmount = alipayAccountBook.getAvailableAmount();
		BigDecimal amount = order.getAmount();
		MakerAlipayAccountFlow entrusteeFlow = new MakerAlipayAccountFlow().setOrderNo(orderNo)
				.setEntrusteeId(payeeEntrusteeId)
				.setAccountBookId(order.getAccountBookId())
				.setType(AlipayMakerAccountFlowType.PAY)
				.setAmount(amount)
				.setPrevAmount(entrusteePrevAmount)
				.setAfterAmount(entrusteePrevAmount.add(amount))
				.setRemark(order.getRemark())
				.setFlowTime(order.getFinishTime());
		entrusteeFlow.insert();
		// 重新刷新下记账本信息
		queryAccountBook(alipayAgreement.getAlipayAgreementNo(), alipayAccountBook);
	}

	private void handleEntrusteePayFailed(MakerAlipayAccountOrder order) {
		// 处理项目状态
		String orderNo = order.getOrderNo();
		EntrustmentProjectItem projectItem = new EntrustmentProjectItem().selectOne(Condition.create().eq("pay_no", orderNo));
		if (projectItem != null) {
			projectItem.setFinishTime(order.getFinishTime()).setState(EntrustProjectState.FAIL).updateById();
			coreEntrustProjectServcie.refreshProjectStatus(projectItem.getImportId());
			//委托发单支付失败 通知riley,项目支付失败 通知给riley
			new Thread(() -> {
				String info = String.format("企业:%s,发布委托接单项目:%s 处理失败;%s(%s)", projectItem.getCompname(), projectItem.getName(), projectItem.getCrowdsourceName(), order.getAlipayErrorMsg());
				commonService.sendEnterpriseWeChatNotice(notificationConfig.getRileyManagerId(), null, 1, info);
				wxMessageService.notifyAdminProjectPublishError(info);
			}).start();
		}
	}

	private void handleEntrustmentProjectPay(MakerAlipayPrincipalOrder order) {
		List<EntrustmentProjectItem> itemList = new EntrustmentProjectItem().selectList(
				Condition.create().eq("transfer_no", order.getOrderNo()).eq("entrustee_id", order.getPayeeEntrusteeId()));
		// 创建项目发票, 转账订单都是将该创客的所有子项目金额一次性转给创客资金记账本. 开票也是一次性合并所有子项目只开一张发票.
		createProjectInvoice(itemList);
		// 执行代付给自然人
		for (EntrustmentProjectItem item : itemList) {
			item.setEntrustState(EntrustState.RECEIVED).setReceiveTime(order.getFinishTime()).updateById();
			AlipayIdentityEnum identityEnum =
					item.getAccountType() == 1 ? AlipayIdentityEnum.LOGON_ID : AlipayIdentityEnum.BANKCARD_ACCOUNT;

			// 执行受托人支付操作, 调用回调方法doAfterEntrustmentProjectPay,处理后续步骤
			entrusteePay(item.getId(), item.getEntrusteeId(), item.getAmount(), item.getName(), identityEnum, item.getAccountNo(),
					item.getPayeeName(), (accountOrder, response) -> doAfterEntrustmentProjectPay(item, accountOrder, response));
		}
	}

	private void createProjectInvoice(List<EntrustmentProjectItem> itemList) {
		if (CollectionUtils.isEmpty(itemList)) return;
		// 新建发票
		EntrustmentProjectItem projectItem = itemList.get(0);
		Integer projectType = projectItem.getProjectType();
		log.info("创建委托接单/创客团发票, 大项目id:{}, 子项目数量:{}, 项目类型为:{}", projectItem.getImportId(), itemList.size(), projectType);
		if (ProjectType.isZhiduoduoProject(projectType)) {
			coreInvoiceService.createEntrustZhiduoduoProjectInvoice(itemList);
		} else if (ProjectType.isCrowdsourceProject(projectType)) {
			// 委托接单-智众包项目, 新建智众包成本发票
			coreInvoiceService.createEntrustCrowdsourceProjectMakerInvoice(itemList);
		}
	}

	private void doAfterEntrustmentProjectPay(EntrustmentProjectItem item, MakerAlipayAccountOrder order,
	                                          AlipayFundTransUniTransferResponse response) {
		// 支付请求完成, 处理后续业务
		if (response != null && response.isSuccess()) {
			item.setPayNo(order.getOrderNo()).setPayTime(new Date()).updateById();
		} else if (response != null) {
			log.info("委托发单, doAfterEntrustmentProjectPay, 发起代付response失败, item id = {}", item.getId());
			item.setAlipayErrorCode(response.getSubCode())
					.setAlipayErrorMsg(response.getSubMsg())
					.setState(EntrustProjectState.FAIL)
					.setFinishTime(new Date())
					.updateById();
		}
		coreEntrustProjectServcie.refreshProjectStatus(item.getImportId());
	}

	public void applyBillEreceipt() {
		makerAlipayAccountOrderMapper.listFinishedOrderWithoutFileId().parallelStream().forEach(order -> {
			try {
				AlipayPrincipalEnum isvPrincipal = getISVPrincipal();
				MakerAlipayAgreement alipayAgreement = makerAlipayAgreementMapper.getByIsvIdAndUserid(isvPrincipal.id,
						order.getEntrusteeId());
				AlipayDataBillEreceiptagentApplyResponse response = aliPayApiService.billEReceiptAgentApply(
						alipayAgreement.getAlipayAgreementNo(), order.getAlipayPayFundOrderId(), isvPrincipal);
				if (response.isSuccess()) {
					order.setReceiptFileId(response.getFileId()).updateById();
				}
			} catch (Exception e) {
				log.error("申请支付宝回单报错, orderid = {}, userid = {}, projectid = {}", order.getId(), order.getEntrusteeId(),
						order.getProjectId(), e);
			}
		});
	}

	public void retrieveBillEreceiptUrl() {
		makerAlipayAccountOrderMapper.listFinishedOrderWithoutDownloadUrl().parallelStream().forEach(order -> {
			try {
				AlipayPrincipalEnum isvPrincipal = getISVPrincipal();
				MakerAlipayAgreement alipayAgreement = makerAlipayAgreementMapper.getByIsvIdAndUserid(isvPrincipal.id,
						order.getEntrusteeId());
				AlipayDataBillAccountbookereceiptQueryResponse response = aliPayApiService.billAccountbookEreceiptQuery(
						alipayAgreement.getAlipayAgreementNo(), order.getReceiptFileId(), isvPrincipal);
				if (response.isSuccess()) {
					order.setReceiptDownloadUrl(response.getDownloadUrl()).updateById();
					coreMakerAlipayService.downloadEreceiptAndSave(order);
				}
			} catch (Exception e) {
				log.error("获取支付宝回单下载链接报错, orderid = {}, userid = {}, projectid = {}", order.getId(), order.getEntrusteeId(),
						order.getProjectId(), e);
			}
		});
	}
}
